package com.yeskery.nut.http;

import com.yeskery.nut.bind.HttpResponseBodyHandler;
import com.yeskery.nut.bind.HttpResponseBodyMetadata;
import com.yeskery.nut.core.InputStreamResource;
import com.yeskery.nut.core.MediaType;
import com.yeskery.nut.core.Order;

import java.io.InputStream;

/**
 * application/octet-stream响应体处理器
 * @author YESKERY
 * 2024/10/11
 */
public class ApplicationOctetStreamHttpResponseBodyHandler implements HttpResponseBodyHandler {

    @Override
    public boolean support(HttpResponseBodyMetadata metadata) {
        Class<?> resultClass = metadata.getResult().getClass();
        return InputStreamResource.class.isAssignableFrom(resultClass) || byte[].class.equals(resultClass) || InputStream.class.isAssignableFrom(resultClass);
    }

    @Override
    public void handle(HttpResponseBodyMetadata metadata) {
        String[] produces = metadata.getAttributes().getProduces();
        Class<?> resultClass = metadata.getResult().getClass();
        if (produces == null || produces.length == 0) {
            if (byte[].class.equals(resultClass)) {
                metadata.getResponse().write((byte[]) metadata.getResult());
            } else {
                InputStream inputStream = InputStreamResource.class.isAssignableFrom(resultClass)
                        ? ((InputStreamResource) metadata.getResult()).getInputStream()
                        : (InputStream) metadata.getResult();
                metadata.getResponse().write(inputStream);
            }
        } else {
            if (byte[].class.equals(resultClass)) {
                metadata.getResponse().write((byte[]) metadata.getResult(), MediaType.getMediaTypeByValue(produces[0]));
            } else {
                InputStream inputStream = InputStreamResource.class.isAssignableFrom(resultClass)
                        ? ((InputStreamResource) metadata.getResult()).getInputStream()
                        : (InputStream) metadata.getResult();
                metadata.getResponse().write(inputStream, MediaType.getMediaTypeByValue(produces[0]));
            }
        }
    }

    @Override
    public int getOrder() {
        return Order.MAX + 1;
    }
}
